/**
 * 用户播放列表管理模块
 * 支持国际化的新架构
 */
const {
	playlistCollection,
	userDeviceCollection,
	patternCollection,
	dbCmd
} = require('../../common/constants')
const {
	ERROR
} = require('../../common/error')
const {
	transformMultiLangData
} = require('../../lib/transform')
const {
	getUserId
} = require('../../common/utils')

// 解析设备标识符（支持deviceId或sn）
const resolveDeviceIdentifier = async (params) => {
	const { deviceId, sn } = params
	
	if (!deviceId && !sn) {
		throw {
			errCode: ERROR.PARAM_REQUIRED,
			errMsgValue: { param: 'deviceId 或 sn' }
		}
	}
	
	let actualDeviceId = deviceId
	let actualSn = sn
	
	// 如果提供了sn但没有deviceId，通过sn查询设备
	if (!actualDeviceId && actualSn) {
		const deviceResult = await userDeviceCollection.where({
			sn: actualSn
		}).get()
		
		if (deviceResult.data.length === 0) {
			throw {
				errCode: ERROR.DEVICE_NOT_FOUND,
				errMsg: '设备不存在'
			}
		}
		
		actualDeviceId = deviceResult.data[0]._id
	}
	
	// 如果提供了deviceId但没有sn，从设备表获取sn
	if (actualDeviceId && !actualSn) {
		const deviceResult = await userDeviceCollection.where({
			$or: [
				{ _id: actualDeviceId },
				{ device_id: actualDeviceId }
			]
		}).get()
		
		if (deviceResult.data.length > 0) {
			actualSn = deviceResult.data[0].sn
		}
	}
	
	return {
		deviceId: actualDeviceId,
		sn: actualSn
	}
}

// 共享的设备权限检查函数
const checkDevicePermission = async (deviceId, userId, context) => {
	// 支持通过_id或device_id查询设备
	const query = {
		$or: [
			{ _id: deviceId },
			{ device_id: deviceId }
		]
	}
	
	const deviceResult = await userDeviceCollection.where(query).get()
	
	if (deviceResult.data.length === 0) {
		throw {
			errCode: ERROR.DEVICE_NOT_FOUND,
			errMsg: context.t ? context.t('device.not.found') : '设备不存在'
		}
	}
	
	const device = deviceResult.data[0]
	
	// 检查用户权限
	if (device.owner_id !== userId && !device.shared_users?.includes(userId)) {
		throw {
			errCode: ERROR.DEVICE_ACCESS_DENIED,
			errMsg: context.t ? context.t('device.access.denied') : '设备访问权限不足'
		}
	}
	
	return device
}

// 获取或创建播放列表
const getOrCreatePlaylist = async (deviceId, userId = null, deviceSn = null) => {
	// 构建查询条件
	const queryCondition = { device_id: deviceId }
	
	// 只有提供userId时才加入userId条件
	if (userId) {
		queryCondition.user_id = userId
	}
	
	// 尝试获取现有播放列表
	const playlistResult = await playlistCollection.where(queryCondition).get()
	
	if (playlistResult.data.length > 0) {
		// 如果已存在播放列表但没有sn字段，则更新添加sn
		const playlist = playlistResult.data[0]
		if (!playlist.sn && deviceSn) {
			await playlistCollection.doc(playlist._id).update({
				sn: deviceSn,
				update_time: new Date()
			})
			playlist.sn = deviceSn
		}
		return playlist
	}
	
	// 如果没有提供deviceSn，从设备表中获取
	if (!deviceSn) {
		const deviceResult = await userDeviceCollection.where({
			$or: [
				{ _id: deviceId },
				{ device_id: deviceId }
			]
		}).get()
		
		if (deviceResult.data.length > 0) {
			deviceSn = deviceResult.data[0].sn
		}
	}
	
	// 创建新的播放列表
	const newPlaylist = {
		device_id: deviceId,
		sn: deviceSn || '', // 添加sn字段
		user_id: userId,
		playlist_name: {
			'zh-Hans': '我的播放列表',
			'en': 'My Playlist'
		},
		patterns: [],
		settings: {
			loop_mode: 'list', // list, single, random
			auto_next: true,
			transition_effect: 'fade'
		},
		total_patterns: 0,
		create_time: new Date(),
		update_time: new Date()
	}
	
	const createResult = await playlistCollection.add(newPlaylist)
	return {
		...newPlaylist,
		_id: createResult.id
	}
}

// 获取图案详情
const getPatternDetails = async (patternId, context) => {
	const patternResult = await patternCollection.where({
		_id: patternId
	}).get()
	
	if (patternResult.data.length === 0) {
		throw {
			errCode: ERROR.PATTERN_NOT_FOUND
		}
	}
	
	// 转换图案数据格式
	const transformedPattern = transformMultiLangData(patternResult.data, context.language || 'zh-Hans', {
		multiLangFields: ['pattern_name', 'description'],
		keepFields: [
			'pattern_id', 'pattern_type', 'difficulty', 'duration', 'play_time',
			'pattern_file', 'thumbnail_url', 'preview_image', 'cover_image', 'tags', 'category',
			'is_premium', 'download_count', 'like_count', 'file_name'
		],
		idMapping: { '_id': 'pattern_id' }
	})[0]
	
	return transformedPattern
}

// 批量添加图案到播放列表
const batchAddPatterns = async (deviceId, userId, patternIds, insertPosition) => {
	// 获取或创建播放列表
	const playlist = await getOrCreatePlaylist(deviceId, userId)
	
	// 验证图案存在性
	const patternResult = await patternCollection.where({
		_id: dbCmd.in(patternIds)
	}).get()
	
	const existingPatternIds = patternResult.data.map(p => p._id)
	const validPatternIds = patternIds.filter(id => existingPatternIds.includes(id))
	const invalidPatternIds = patternIds.filter(id => !existingPatternIds.includes(id))
	
	// 过滤已存在的图案
	const playlistPatternIds = playlist.patterns.map(p => p.pattern_id)
	const newPatternIds = validPatternIds.filter(id => !playlistPatternIds.includes(id))
	const duplicatePatternIds = validPatternIds.filter(id => playlistPatternIds.includes(id))
	
	// 确定插入位置
	const targetPosition = insertPosition !== undefined ? insertPosition : playlist.patterns.length
	
	// 创建新图案对象
	const newPatterns = newPatternIds.map((patternId, index) => ({
		pattern_id: patternId,
		sort_order: targetPosition + index,
		added_time: new Date()
	}))
	
	// 如果指定插入位置，调整现有图案的排序
	if (insertPosition !== undefined && insertPosition < playlist.patterns.length) {
		playlist.patterns.forEach(pattern => {
			if (pattern.sort_order >= targetPosition) {
				pattern.sort_order += newPatterns.length
			}
		})
	}
	
	// 添加新图案
	playlist.patterns.push(...newPatterns)
	playlist.patterns.sort((a, b) => a.sort_order - b.sort_order)
	
	// 更新播放列表
	await playlistCollection.doc(playlist._id).update({
		patterns: playlist.patterns,
		total_patterns: playlist.patterns.length,
		update_time: new Date()
	})
	
	// 获取新添加图案的完整详情，包含pattern_file等信息
	const addedPatternDetails = []
	for (const patternId of newPatternIds) {
		const patternDetail = patternResult.data.find(p => p._id === patternId)
		if (patternDetail) {
			addedPatternDetails.push({
				pattern_id: patternId,
				pattern_file: patternDetail.pattern_file || '',
				file_name: patternDetail.file_name || `${patternId}.thr`,
				pattern_name: patternDetail.pattern_name,
				sort_order: newPatterns.find(p => p.pattern_id === patternId)?.sort_order || 0,
				added_time: newPatterns.find(p => p.pattern_id === patternId)?.added_time || new Date()
			})
		}
	}
	
	return {
		addedCount: newPatterns.length,
		skippedCount: duplicatePatternIds.length + invalidPatternIds.length,
		addedPatterns: newPatterns,
		addedPatternDetails: addedPatternDetails,
		skippedPatterns: [...duplicatePatternIds, ...invalidPatternIds]
	}
}

module.exports = {
	/**
	 * 获取设备播放列表
	 * @param {object} params 查询参数
	 * @param {string} params.deviceId 设备ID（可选，与sn二选一）
	 * @param {string} params.sn 设备序列号（可选，与deviceId二选一）
	 * @returns {object} 播放列表
	 */
	async getPlaylist(params) {
		try {
			// 解析设备标识符
			const { deviceId, sn } = await resolveDeviceIdentifier(params)
			
			// 注意: 播放列表只按设备查询，不需要userId过滤
			// 因为同一设备可能被多个用户共享，播放列表是设备级别的
			
			// 获取或创建播放列表（传入sn参数，不需要userId）
			const userId = null // 不使用userId过滤
			const playlist = await getOrCreatePlaylist(deviceId, userId, sn)
			
			// 获取播放列表中的图案详情
			if (playlist.patterns && playlist.patterns.length > 0) {
				const patternIds = playlist.patterns.map(p => p.pattern_id)
				const patternResult = await patternCollection.where({
					_id: dbCmd.in(patternIds)
				}).get()
				
				// 获取当前请求的语言
				const language = this.language || 'zh-Hans'
				
				// 转换图案数据格式
				const transformedPatterns = transformMultiLangData(patternResult.data, language, {
					multiLangFields: ['pattern_name', 'description'],
					keepFields: [
						'pattern_id', 'pattern_type', 'difficulty', 'duration', 'play_time',
						'pattern_file', 'file_name', 'file_url', 'thumbnail_url', 'preview_image', 'cover_image', 'tags', 'category',
						'is_premium', 'download_count', 'like_count'
					],
					idMapping: { '_id': 'pattern_id' }
				})
				
				// 按播放列表顺序重新排列图案
				const orderedPatterns = []
				playlist.patterns.forEach(playlistPattern => {
					const pattern = transformedPatterns.find(p => p.pattern_id === playlistPattern.pattern_id)
					if (pattern) {
						orderedPatterns.push({
							...pattern,
							sort_order: playlistPattern.sort_order,
							added_time: playlistPattern.added_time
						})
					}
				})
				
				playlist.patterns = orderedPatterns
			}
			
			// 转换播放列表数据格式
			const transformedPlaylist = transformMultiLangData([playlist], this.language || 'zh-Hans', {
				multiLangFields: ['playlist_name'],
				keepFields: [
					'device_id', 'user_id', 'patterns', 'settings',
					'create_time', 'update_time', 'total_patterns'
				],
				idMapping: { '_id': 'playlist_id' }
			})[0]
			
			return {
				errCode: 0,
				errMsg: this.t ? this.t('playlist.get_success') : '获取播放列表成功',
				data: transformedPlaylist
			}
		} catch (error) {
			console.error('getPlaylist error:', error)
			if (error.errCode) {
				throw error
			}
			throw {
				errCode: ERROR.SYSTEM_ERROR,
				errMsg: this.t ? this.t('playlist.get_failed') : '获取播放列表失败'
			}
		}
	},
	
	/**
	 * 添加图案到播放列表
	 * @param {object} params 添加参数
	 * @param {string} params.deviceId 设备ID（可选，与sn二选一）
	 * @param {string} params.sn 设备序列号（可选，与deviceId二选一）
	 * @param {string} params.patternId 图案ID
	 * @param {number} params.sortOrder 排序位置（可选）
	 * @returns {object} 添加结果
	 */
	async addPatternToPlaylist(params) {
		const { patternId, sortOrder } = params
		
		if (!patternId) {
			throw {
				errCode: ERROR.PARAM_REQUIRED,
				errMsgValue: { param: 'patternId' }
			}
		}
		
		try {
			// 解析设备标识符
			const { deviceId, sn } = await resolveDeviceIdentifier(params)
			
			// 注意: 播放列表是设备级别的，不需要用户权限检查
			
			// 验证图案是否存在
			const patternDetails = await getPatternDetails(patternId, this)
			
			// 获取或创建播放列表（不需要userId）
			const playlist = await getOrCreatePlaylist(deviceId, null, sn)
			
			// 检查图案是否已在播放列表中
			const existingPattern = playlist.patterns.find(p => p.pattern_id === patternId)
			if (existingPattern) {
				throw {
					errCode: ERROR.PATTERN_ALREADY_IN_PLAYLIST
				}
			}
			
			// 确定排序位置
			const targetSortOrder = sortOrder !== undefined ? sortOrder : playlist.patterns.length
			
			// 添加图案到播放列表
			const newPattern = {
				pattern_id: patternId,
				sort_order: targetSortOrder,
				added_time: new Date()
			}
			
			// 如果指定位置，需要调整其他图案的排序
			if (sortOrder !== undefined && sortOrder < playlist.patterns.length) {
				playlist.patterns.forEach(pattern => {
					if (pattern.sort_order >= targetSortOrder) {
						pattern.sort_order += 1
					}
				})
			}
			
			playlist.patterns.push(newPattern)
			playlist.patterns.sort((a, b) => a.sort_order - b.sort_order)
			
			// 更新播放列表
			await playlistCollection.doc(playlist._id).update({
				patterns: playlist.patterns,
				total_patterns: playlist.patterns.length,
				update_time: new Date()
			})
			
			return {
				errCode: 0,
				errMsg: this.t ? this.t('playlist.pattern_added_success') : '图案添加成功',
				data: {
					pattern: {
						...patternDetails,
						sort_order: targetSortOrder,
						added_time: newPattern.added_time
					}
				}
			}
		} catch (error) {
			console.error('addPatternToPlaylist error:', error)
			if (error.errCode) {
				throw error
			}
			throw {
				errCode: ERROR.SYSTEM_ERROR,
				errMsg: this.t ? this.t('playlist.pattern_add_failed') : '添加图案失败'
			}
		}
	},
	
	/**
	 * 从播放列表移除图案
	 * @param {object} params 移除参数
	 * @param {string} params.deviceId 设备ID（可选，与sn二选一）
	 * @param {string} params.sn 设备序列号（可选，与deviceId二选一）
	 * @param {string} params.patternId 图案ID
	 * @returns {object} 移除结果
	 */
	async removePatternFromPlaylist(params) {
		const { patternId } = params
		
		if (!patternId) {
			throw {
				errCode: ERROR.PARAM_REQUIRED,
				errMsgValue: { param: 'patternId' }
			}
		}
		
		try {
			// 解析设备标识符
			const { deviceId } = await resolveDeviceIdentifier(params)
			
			// 注意: 播放列表是设备级别的，不需要用户权限检查
			
			// 获取播放列表（只按设备ID查询）
			const playlistResult = await playlistCollection.where({
				device_id: deviceId
			}).get()
			
			if (playlistResult.data.length === 0) {
				throw {
					errCode: ERROR.PLAYLIST_NOT_FOUND
				}
			}
			
			const playlist = playlistResult.data[0]
			
			// 查找要移除的图案
			const patternIndex = playlist.patterns.findIndex(p => p.pattern_id === patternId)
			if (patternIndex === -1) {
				throw {
					errCode: ERROR.PATTERN_NOT_IN_PLAYLIST
				}
			}
			
			const removedPattern = playlist.patterns[patternIndex]
			
			// 移除图案
			playlist.patterns.splice(patternIndex, 1)
			
			// 重新调整排序
			playlist.patterns.forEach((pattern, index) => {
				pattern.sort_order = index
			})
			
			// 更新播放列表
			await playlistCollection.doc(playlist._id).update({
				patterns: playlist.patterns,
				total_patterns: playlist.patterns.length,
				update_time: new Date()
			})
			
			return {
				errCode: 0,
				errMsg: this.t ? this.t('playlist.pattern_removed_success') : '图案移除成功',
				data: {
					removed_pattern: removedPattern
				}
			}
		} catch (error) {
			console.error('removePatternFromPlaylist error:', error)
			if (error.errCode) {
				throw error
			}
			throw {
				errCode: ERROR.SYSTEM_ERROR,
				errMsg: this.t ? this.t('playlist.pattern_remove_failed') : '移除图案失败'
			}
		}
	},
	
	/**
	 * 重新排序播放列表中的图案
	 * @param {object} params 排序参数
	 * @param {string} params.deviceId 设备ID（可选，与sn二选一）
	 * @param {string} params.sn 设备序列号（可选，与deviceId二选一）
	 * @param {Array} params.patternOrders 图案排序数组 [{patternId, sortOrder}]
	 * @returns {object} 排序结果
	 */
	async reorderPatternsInPlaylist(params) {
		const { patternOrders } = params
		
		if (!patternOrders || !Array.isArray(patternOrders)) {
			throw {
				errCode: ERROR.PARAM_REQUIRED,
				errMsgValue: { param: 'patternOrders' }
			}
		}
		
		try {
			// 解析设备标识符
			const { deviceId } = await resolveDeviceIdentifier(params)
			
			// 注意: 播放列表是设备级别的，不需要用户权限检查
			
			// 获取播放列表（只按设备ID查询）
			const playlistResult = await playlistCollection.where({
				device_id: deviceId
			}).get()
			
			if (playlistResult.data.length === 0) {
				throw {
					errCode: ERROR.PLAYLIST_NOT_FOUND
				}
			}
			
			const playlist = playlistResult.data[0]
			
			// 验证所有图案都在播放列表中
			const playlistPatternIds = playlist.patterns.map(p => p.pattern_id)
			const orderPatternIds = patternOrders.map(o => o.patternId)
			
			const missingPatterns = orderPatternIds.filter(id => !playlistPatternIds.includes(id))
			if (missingPatterns.length > 0) {
				throw {
					errCode: ERROR.PATTERN_NOT_IN_PLAYLIST
				}
			}
			
			// 重新排序
			patternOrders.forEach(order => {
				const pattern = playlist.patterns.find(p => p.pattern_id === order.patternId)
				if (pattern) {
					pattern.sort_order = order.sortOrder
				}
			})
			
			// 按新的排序排列
			playlist.patterns.sort((a, b) => a.sort_order - b.sort_order)
			
			// 更新播放列表
			await playlistCollection.doc(playlist._id).update({
				patterns: playlist.patterns,
				update_time: new Date()
			})
			
			return {
				errCode: 0,
				errMsg: this.t ? this.t('playlist.reorder_success') : '排序更新成功',
				data: {
					patterns: playlist.patterns
				}
			}
		} catch (error) {
			console.error('reorderPatternsInPlaylist error:', error)
			if (error.errCode) {
				throw error
			}
			throw {
				errCode: ERROR.SYSTEM_ERROR,
				errMsg: this.t ? this.t('playlist.reorder_failed') : '排序更新失败'
			}
		}
	},
	
	/**
	 * 批量添加图案到播放列表
	 * @param {object} params 批量添加参数
	 * @param {string} params.deviceId 设备ID
	 * @param {Array} params.patternIds 图案ID数组
	 * @param {number} params.insertPosition 插入位置（可选）
	 * @returns {object} 批量添加结果
	 */
	async batchAddPatternsToPlaylist(params) {
		const { deviceId, patternIds, insertPosition } = params
		
		if (!deviceId || !patternIds || !Array.isArray(patternIds) || patternIds.length === 0) {
			throw {
				errCode: ERROR.PARAM_REQUIRED,
				errMsgValue: { param: !deviceId ? 'deviceId' : 'patternIds' }
			}
		}
		
		try {
			// 注意: 播放列表是设备级别的，不需要用户权限检查
			
			// 批量验证图案（不需要userId）
			const results = await batchAddPatterns(deviceId, null, patternIds, insertPosition)
			
			return {
				errCode: 0,
				errMsg: this.t ? this.t('playlist.batch_add_success') : '批量添加成功',
				data: {
					added_count: results.addedCount,
					skipped_count: results.skippedCount,
					added_patterns: results.addedPatterns,
					added_pattern_details: results.addedPatternDetails,
					skipped_patterns: results.skippedPatterns
				}
			}
		} catch (error) {
			console.error('batchAddPatternsToPlaylist error:', error)
			if (error.errCode) {
				throw error
			}
			throw {
				errCode: ERROR.SYSTEM_ERROR,
				errMsg: this.t ? this.t('playlist.batch_add_failed') : '批量添加失败'
			}
		}
	},
	
	/**
	 * 清空播放列表
	 * @param {object} params 清空参数
	 * @param {string} params.deviceId 设备ID（可选，与sn二选一）
	 * @param {string} params.sn 设备序列号（可选，与deviceId二选一）
	 * @returns {object} 清空结果
	 */
	async clearPlaylist(params) {
		try {
			// 注意: 播放列表是设备级别的，不需要用户权限检查
			
			// 解析设备标识符
			const { deviceId } = await resolveDeviceIdentifier(params)
			
			// 获取播放列表（只按设备ID查询）
			const playlistResult = await playlistCollection.where({
				device_id: deviceId
			}).get()
			
			if (playlistResult.data.length === 0) {
				throw {
					errCode: ERROR.PLAYLIST_NOT_FOUND
				}
			}
			
			const playlist = playlistResult.data[0]
			const clearedCount = playlist.patterns.length
			
			// 清空播放列表
			await playlistCollection.doc(playlist._id).update({
				patterns: [],
				total_patterns: 0,
				update_time: new Date()
			})
			
			return {
				errCode: 0,
				errMsg: this.t ? this.t('playlist.clear_success') : '播放列表清空成功',
				data: {
					cleared_count: clearedCount
				}
			}
		} catch (error) {
			console.error('clearPlaylist error:', error)
			if (error.errCode) {
				throw error
			}
			throw {
				errCode: ERROR.SYSTEM_ERROR,
				errMsg: this.t ? this.t('playlist.clear_failed') : '清空播放列表失败'
			}
		}
	},
	
	/**
	 * 批量添加图案到播放列表末尾
	 * @param {object} params 批量添加参数
	 * @param {string|Array} params.deviceId 设备ID（单个设备）或设备ID数组（多个设备）（可选，与sn二选一）
	 * @param {string|Array} params.sn 设备序列号（单个设备）或设备序列号数组（多个设备）（可选，与deviceId二选一）
	 * @param {Array} params.patternIds 图案ID数组
	 * @returns {object} 批量添加结果
	 */
	async batchAddPatternsToEnd(params) {
		const { patternIds } = params
		
		if (!patternIds || !Array.isArray(patternIds) || patternIds.length === 0) {
			throw {
				errCode: ERROR.PARAM_REQUIRED,
				errMsgValue: { param: 'patternIds' }
			}
		}

		try {
			// 注意: 播放列表是设备级别的，不需要用户权限检查
			
			// 解析设备标识符（支持单个或多个）
			let deviceIds = []
			
			if (params.deviceId) {
				deviceIds = Array.isArray(params.deviceId) ? params.deviceId : [params.deviceId]
			} else if (params.sn) {
				// 如果提供的是sn，需要转换为deviceId
				const sns = Array.isArray(params.sn) ? params.sn : [params.sn]
				for (const sn of sns) {
					const { deviceId } = await resolveDeviceIdentifier({ sn })
					deviceIds.push(deviceId)
				}
			} else {
				throw {
					errCode: ERROR.PARAM_REQUIRED,
					errMsgValue: { param: 'deviceId 或 sn' }
				}
			}
			
			if (deviceIds.length === 0) {
				throw {
					errCode: ERROR.PARAM_REQUIRED,
					errMsgValue: { param: 'deviceId 或 sn' }
				}
			}

			// 批量处理多个设备
			const results = []
			const errors = []

			for (const currentDeviceId of deviceIds) {
				try {
					// 批量添加到末尾（不指定插入位置）
					const result = await batchAddPatterns(currentDeviceId, null, patternIds)
					
					results.push({
						deviceId: currentDeviceId,
						success: true,
						added_count: result.addedCount,
						skipped_count: result.skippedCount,
						added_patterns: result.addedPatterns,
						added_pattern_details: result.addedPatternDetails,
						skipped_patterns: result.skippedPatterns
					})
				} catch (error) {
					console.error(`batchAddPatternsToEnd error for device ${currentDeviceId}:`, error)
					errors.push({
						deviceId: currentDeviceId,
						success: false,
						error: error.errMsg || error.message || '操作失败'
					})
				}
			}

			// 构建返回结果
			const successCount = results.length
			const errorCount = errors.length
			const totalProcessed = successCount + errorCount
			
			// 合并所有成功设备的添加详情（用于单设备场景）
			const allAddedPatternDetails = results.length > 0 && results[0].added_pattern_details 
				? results[0].added_pattern_details 
				: []

			return {
				errCode: errorCount === 0 ? 0 : ERROR.PARTIAL_SUCCESS,
				errMsg: errorCount === 0 
					? (this.t('playlist.batch_add_to_end_success') || '批量添加到播放列表末尾成功')
					: `${successCount}/${totalProcessed} 个设备操作成功`,
				data: {
					total_devices: totalProcessed,
					success_count: successCount,
					error_count: errorCount,
					addedPatternDetails: allAddedPatternDetails,  // 方便单设备场景使用
					addedCount: results.length > 0 ? results[0].added_count : 0,
					skippedCount: results.length > 0 ? results[0].skipped_count : 0,
					results: results,
					errors: errors
				}
			}
		} catch (error) {
			console.error('batchAddPatternsToEnd error:', error)
			if (error.errCode) {
				throw error
			}
			throw {
				errCode: ERROR.SYSTEM_ERROR,
				errMsg: this.t ? this.t('playlist.batch_add_to_end_failed') : '批量添加到播放列表末尾失败'
			}
		}
	},

	/**
	 * 立即播放（清空播放列表并添加指定图案）
	 * @param {object} params 立即播放参数
	 * @param {string|Array} params.deviceId 设备ID（单个设备）或设备ID数组（多个设备）
	 * @param {Array} params.patternIds 图案ID数组
	 * @returns {object} 立即播放结果
	 */
	async playNow(params) {
		const { patternIds } = params
		
		if (!patternIds || !Array.isArray(patternIds) || patternIds.length === 0) {
			throw {
				errCode: ERROR.PARAM_REQUIRED,
				errMsgValue: { param: 'patternIds' }
			}
		}
		
		try {
			// 注意: 播放列表是设备级别的，不需要用户权限检查
			
			// 解析设备标识符（支持单个或多个）
			let deviceIds = []
			
			if (params.deviceId) {
				deviceIds = Array.isArray(params.deviceId) ? params.deviceId : [params.deviceId]
			} else if (params.sn) {
				// 如果提供的是sn，需要转换为deviceId
				const sns = Array.isArray(params.sn) ? params.sn : [params.sn]
				for (const sn of sns) {
					const { deviceId } = await resolveDeviceIdentifier({ sn })
					deviceIds.push(deviceId)
				}
			} else {
				throw {
					errCode: ERROR.PARAM_REQUIRED,
					errMsgValue: { param: 'deviceId 或 sn' }
				}
			}
			
			if (deviceIds.length === 0) {
				throw {
					errCode: ERROR.PARAM_REQUIRED,
					errMsgValue: { param: 'deviceId 或 sn' }
				}
			}

			// 验证图案存在性（只需验证一次）
			const patternResult = await patternCollection.where({
				_id: dbCmd.in(patternIds)
			}).get()
			
			const existingPatternIds = patternResult.data.map(p => p._id)
			const validPatternIds = patternIds.filter(id => existingPatternIds.includes(id))

			if (validPatternIds.length === 0) {
				throw {
					errCode: ERROR.PATTERN_NOT_FOUND,
					errMsg: this.t ? this.t('pattern.not.found') : '未找到有效的图案'
				}
			}

			// 批量处理多个设备
			const failedDevices = []
			let successCount = 0

			for (const currentDeviceId of deviceIds) {
				try {
					// 获取或创建播放列表
					const playlist = await getOrCreatePlaylist(currentDeviceId, null)
					
					// 创建新的播放列表图案
					const newPatterns = validPatternIds.map((patternId, index) => ({
						pattern_id: patternId,
						sort_order: index,
						added_time: new Date()
					}))
					
					// 直接替换播放列表
					await playlistCollection.doc(playlist._id).update({
						patterns: newPatterns,
						total_patterns: newPatterns.length,
						update_time: new Date()
					})
					
					successCount++
				} catch (error) {
					console.error(`playNow error for device ${currentDeviceId}:`, error)
					failedDevices.push({
						deviceId: currentDeviceId,
						error: error.errMsg || error.message || '操作失败'
					})
				}
			}

			// 如果全部失败，抛出错误
			if (successCount === 0) {
				throw {
					errCode: ERROR.SYSTEM_ERROR,
					errMsg: this.t ? this.t('playlist.play_now_failed') : '立即播放设置失败',
					failedDevices
				}
			}
			
			// 构建返回的图案详情，用于MQTT
			const patternDetails = []
			for (const patternId of validPatternIds) {
				const patternDetail = patternResult.data.find(p => p._id === patternId)
				if (patternDetail) {
					patternDetails.push({
						pattern_id: patternId,
						pattern_file: patternDetail.pattern_file || '',
						file_name: patternDetail.file_name || `${patternId}.thr`,
						pattern_name: patternDetail.pattern_name
					})
				}
			}

			return {
				errCode: 0,
				errMsg: failedDevices.length === 0 
					? (this.t ? this.t('playlist.play_now_success') : '立即播放设置成功')
					: `${successCount}/${deviceIds.length} 个设备设置成功`,
				data: {
					totalDevices: deviceIds.length,
					successCount,
					failedCount: failedDevices.length,
					failedDevices: failedDevices.length > 0 ? failedDevices : undefined,
					addedPatternDetails: patternDetails  // 统一字段名
				}
			}
		} catch (error) {
			console.error('playNow error:', error)
			if (error.errCode) {
				throw error
			}
			throw {
				errCode: ERROR.SYSTEM_ERROR,
				errMsg: this.t ? this.t('playlist.play_now_failed') : '立即播放设置失败'
			}
		}
	},

	/**
	 * 更新播放列表设置
	 * @param {object} params 更新参数
	 * @param {string} params.deviceId 设备ID
	 * @param {object} params.settings 播放设置
	 * @returns {object} 更新结果
	 */
	async updatePlaylistSettings(params) {
		const { deviceId, settings } = params
		
		if (!deviceId || !settings) {
			throw {
				errCode: ERROR.PARAM_REQUIRED,
				errMsgValue: { param: !deviceId ? 'deviceId' : 'settings' }
			}
		}
		
		try {
			// 注意: 播放列表是设备级别的，不需要用户权限检查
			
			// 获取播放列表（只按设备ID查询）
			const playlistResult = await playlistCollection.where({
				device_id: deviceId
			}).get()
			
			if (playlistResult.data.length === 0) {
				throw {
					errCode: ERROR.PLAYLIST_NOT_FOUND
				}
			}
			
			const playlist = playlistResult.data[0]
			
			// 合并设置
			const updatedSettings = {
				...playlist.settings,
				...settings
			}
			
			// 更新播放列表设置
			await playlistCollection.doc(playlist._id).update({
				settings: updatedSettings,
				update_time: new Date()
			})
			
			return {
				errCode: 0,
				errMsg: this.t ? this.t('playlist.settings_updated_success') : '播放列表设置更新成功',
				data: {
					settings: updatedSettings
				}
			}
		} catch (error) {
			console.error('updatePlaylistSettings error:', error)
			if (error.errCode) {
				throw error
			}
			throw {
				errCode: ERROR.SYSTEM_ERROR,
				errMsg: this.t ? this.t('playlist.settings_update_failed') : '更新播放列表设置失败'
			}
		}
	},

	/**
	 * 更新播放模式
	 * @param {Object} params 参数对象
	 * @param {string} params.deviceId 设备ID
	 * @param {number} params.playMode 播放模式：0-顺序播放，1-随机播放，2-单曲循环
	 * @returns {Promise<Object>} 返回更新结果
	 */
	async updatePlayMode(params) {
		const { deviceId, playMode } = params
		
		// 参数验证
		if (!deviceId) {
			return {
				errCode: ERROR.PARAM_REQUIRED,
				errMsg: this.t ? this.t('param.device_id_required') : '设备ID不能为空',
				data: null
			}
		}
		
		if (playMode === undefined || playMode === null) {
			return {
				errCode: ERROR.PARAM_REQUIRED,
				errMsg: this.t ? this.t('param.play_mode_required') : '播放模式不能为空',
				data: null
			}
		}
		
		// 验证播放模式值
		if (![0, 1, 2].includes(playMode)) {
			return {
				errCode: ERROR.PARAM_INVALID,
				errMsg: this.t ? this.t('param.play_mode_invalid') : '播放模式值无效，必须为0（顺序）、1（随机）或2（单曲循环）',
				data: null
			}
		}
		
		try {
			// 注意: 播放列表是设备级别的，不需要用户权限检查
			
			// 查找播放列表
			const playlistQuery = {
				device_id: deviceId
			}
			
			const playlistResult = await playlistCollection.where(playlistQuery).get()
			
			if (playlistResult.data.length === 0) {
				// 如果播放列表不存在，创建一个新的
				const newPlaylist = {
					device_id: deviceId,
					patterns: [],
					current_index: 0,
					play_mode: playMode,
					auto_play: true,
					create_time: new Date(),
					update_time: new Date()
				}
				
				const createResult = await playlistCollection.add(newPlaylist)
				
				// 返回播放模式名称
				const playModeNames = {
					0: this.t ? this.t('playlist.mode.sequential') : '顺序播放',
					1: this.t ? this.t('playlist.mode.random') : '随机播放',
					2: this.t ? this.t('playlist.mode.single_loop') : '单曲循环'
				}
				
				return {
					errCode: 0,
					errMsg: this.t ? this.t('playlist.play_mode_updated_success') : '播放模式更新成功',
					data: {
						playlistId: createResult.id,
						playMode: playMode,
						playModeName: playModeNames[playMode],
						isNewPlaylist: true
					}
				}
			}
			
			const playlist = playlistResult.data[0]
			
			// 更新播放模式
			await playlistCollection.doc(playlist._id).update({
				play_mode: playMode,
				update_time: new Date()
			})
			
			// 返回播放模式名称
			const playModeNames = {
				0: this.t ? this.t('playlist.mode.sequential') : '顺序播放',
				1: this.t ? this.t('playlist.mode.random') : '随机播放',
				2: this.t ? this.t('playlist.mode.single_loop') : '单曲循环'
			}
			
			return {
				errCode: 0,
				errMsg: this.t ? this.t('playlist.play_mode_updated_success') : '播放模式更新成功',
				data: {
					playlistId: playlist._id,
					playMode: playMode,
					playModeName: playModeNames[playMode],
					previousPlayMode: playlist.play_mode,
					isNewPlaylist: false
				}
			}
			
		} catch (error) {
			console.error('[PLAYLIST] updatePlayMode error:', error)
			
			// 如果是已知错误，直接返回
			if (error.errCode) {
				return {
					errCode: error.errCode,
					errMsg: error.errMsg || (this.t ? this.t('playlist.play_mode_update_failed') : '播放模式更新失败'),
					data: null
				}
			}
			
			// 系统错误
			return {
				errCode: ERROR.SYSTEM_ERROR,
				errMsg: this.t ? this.t('system.error') : '系统错误',
				data: null
			}
		}
	}
}
